home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Find/Search *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991, 1992 by H. Roy Engehausen. All *)
- (* rights reserved. *)
- (* *)
- (*===========================================================================*)
-
- (*===========================================================================*)
- (* Search for a msg *)
- (* Types of searches: *)
- (* ' ' = By number *)
- (* '#' = By number (but no termination) *)
- (* 'C' = User class *)
- (* 'D' = By date *)
- (* 'E' = Find to a user at this BBS (For servers) *)
- (* 'G' = Currently logged on station *)
- (* 'K' = By flag and number *)
- (* 'L' = Find last "n" msgs *)
- (* 'M' = find all messages either to or from user *)
- (* 'O' = find all messages at a user - Check to field only. *)
- (* Must be forwardable and have no H address *)
- (* 'Q' = find all read messages to user *)
- (* 'R' = find all unread messages to user *)
- (* 'S' = find all messages with matching pattern in Subj *)
- (* 'T' = find all messages of a certain type *)
- (* '$' = find all messages with matching pattern in BID *)
- (* '<' = find all messages from a user *)
- (* '>' = find all messages to a user *)
- (* '@' = find all messages to a bbs *)
- (* '%' = find all messages from a bbs *)
- (* *)
- (* WARNING !!!! Indentation rules not fully followed to improve code *)
- (* size and execution speed *)
- (* *)
- (*===========================================================================*)
-
- PROCEDURE search_msg(search : search_block_ptr);
-
- {$UNDEF DEBUG3A}
- {$UNDEF DEBUG3B}
- {$UNDEF DEBUG3C} (* Used to debug intermittent actions *)
- {$UNDEF DEBUG3D} (* Debug back search block *)
-
- VAR
- ascend : BOOLEAN;
- b : BOOLEAN;
- found : BOOLEAN;
- do_hide_check : BOOLEAN;
- i : BYTE;
- msg_index_current : msg_index_ptr;
- nok_switch : BOOLEAN;
- our_search : search_block_type;
- save_last : msg_index_ptr;
- this_search_block : search_block_ptr;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize *)
- (*-----------------------------------------------------------------------*)
-
- this_search_block := search;
-
- (*-----------------------------------------------------------------------*)
- (* Set main no kill switch and directions *)
- (*-----------------------------------------------------------------------*)
-
- nok_switch := TRUE;
- ascend := FALSE;
-
- {$IFDEF POINT_CHK}
- test_pointer(this_search_block);
- {$ENDIF}
-
- REPEAT
-
- {$IFDEF POINT_CHK}
- test_pointer(this_search_block);
- {$ENDIF}
-
- ascend := ascend OR this_search_block^.search_ascend;
- nok_switch := nok_switch AND this_search_block^.search_nok;
- this_search_block := this_search_block^.search_next;
-
- UNTIL (this_search_block = NIL) OR NOT nok_switch;
-
- (*-----------------------------------------------------------------------*)
- (* More initialization *)
- (*-----------------------------------------------------------------------*)
-
- our_search := search^;
- this_search_block := search;
-
- (*-----------------------------------------------------------------------*)
- (* Debugging *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG3A}
- REPEAT
- WRITELN('Type = ', this_search_block^.search_type);
- WRITELN('Ascend = ', this_search_block^.search_ascend);
- WRITELN('Above = ', this_search_block^.search_above);
- WRITELN('NOK = ', this_search_block^.search_nok);
- WRITELN('Msg_No = ', this_search_block^.search_msg_no);
- DELAY(1000);
- this_search_block := this_search_block^.search_next;
- UNTIL this_search_block = NIL;
- this_search_block := search;
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Debugging *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG3B}
- trace_data('M31', this_search_block^.search_msg_no,
- our_search.search_last,
- '');
- {$ENDIF}
-
- {$IFDEF DEBUG3C}
- trace_data('MF3 1', ORD(our_search.search_type),
- our_search.search_last,
- '');
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Initialize for the search loop. The start of the search should *)
- (* be the next msg from our last hit. If this is the start of a *)
- (* search then use one of the ends of the chain. Note that there *)
- (* are two chains: the main chain of all messages and the "n_list" *)
- (* chain. The latter contains messages that may be awaiting forward. *)
- (* This chain is a lot shorter and speeds up forwarding *)
- (*-----------------------------------------------------------------------*)
-
- IF our_search.search_last <> NIL THEN
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(our_search.search_last);
- {$ENDIF}
-
- IF NOT our_search.search_one_only THEN
- BEGIN;
- IF ascend THEN
- msg_index_current := our_search.search_last^.msg_i_next
- ELSE
- msg_index_current := our_search.search_last^.msg_i_last;
- END
- ELSE
- msg_index_current := our_search.search_last;
- END
- ELSE
- BEGIN;
- IF ascend THEN
- msg_index_current := msg_index_start
- ELSE
- msg_index_current := msg_index_end;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Debugging *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG3B}
- trace_data('M32', this_search_block^.search_msg_no,
- our_search.search_last,
- '');
- {$ENDIF}
-
- {$IFDEF DEBUG3C}
- trace_data('MF3 2', ORD(our_search.search_type),
- our_search.search_last,
- '');
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Set our switches off and prep the save pointer. *)
- (*-----------------------------------------------------------------------*)
-
- found := FALSE;
- save_last := our_search.search_last;
-
- do_hide_check := NOT our_search.search_one_only;
-
- (*-----------------------------------------------------------------------*)
- (* This loop is the search loop *)
- (*-----------------------------------------------------------------------*)
-
- WHILE (NOT found) AND (msg_index_current <> NIL) DO
- BEGIN;
-
- (*------------------------------------------------------------------*)
- (* If we were not at the top of the chain, set us back to the top *)
- (*------------------------------------------------------------------*)
-
- IF this_search_block <> search THEN
- BEGIN;
- this_search_block := search;
- our_search := search^;
- END;
-
- REPEAT
-
- (*---------------------------------------------------------------------------*)
- (* Indentation VIOLATION starts here *)
- (*---------------------------------------------------------------------------*)
-
- (*---------------------------------------------------------------------------*)
- (* See if current message meets criteria *)
- (*---------------------------------------------------------------------------*)
-
- CASE our_search.search_type OF
-
- (*-------------------------------------------------------------------------*)
- (* '<' = find all messages from a user *)
- (* '>' = find all messages to a user *)
- (* '@' = find all messages to a BBS *)
- (* '@' = find all messages from a BBS *)
- (* 'E' = Find to a user at this BBS (For servers) *)
- (* 'S' = find all messages with matching string in subj *)
- (* '$' = find all messages with matching string in bid *)
- (* '.' = find all messages with matching string in hier address *)
- (*-------------------------------------------------------------------------*)
-
- '@' : found := match_str(msg_index_current^.msg_i_mb.msg_to_at,
- our_search.search_str);
- '>' : found := match_str(msg_index_current^.msg_i_mb.msg_to,
- our_search.search_str);
- '<' : found := match_str(msg_index_current^.msg_i_mb.msg_from,
- our_search.search_str);
- '.' : found := match_str(msg_index_current^.msg_i_mb.msg_to_h,
- our_search.search_str);
- '$' : found := match_str(msg_index_current^.msg_i_mb.msg_bid,
- our_search.search_str);
- '%' : found := match_str(msg_index_current^.msg_i_mb.msg_from_at,
- our_search.search_str);
- 'E' : found := match_str(msg_index_current^.msg_i_mb.msg_to,
- our_search.search_str)
- AND ((msg_index_current^.msg_i_mb.msg_to_at = '')
- OR (msg_index_current^.msg_i_mb.msg_to_at =
- opt_block.this_bb_sign));
- 'S' : found := match_str(upcase_str(msg_index_current^.msg_i_mb.msg_subj),
- our_search.search_str);
-
- (*-------------------------------------------------------------------------*)
- (* ' ' = search by number (either above or below a value) *)
- (* '#' = search by number (either above or below a value) *)
- (*-------------------------------------------------------------------------*)
-
- ' ', '#' : BEGIN;
-
- IF our_search.search_above THEN
- found :=
- (msg_index_current^.msg_i_mb.msg_number >=
- our_search.search_msg_no)
- ELSE
- found :=
- (msg_index_current^.msg_i_mb.msg_number <=
- our_search.search_msg_no);
-
- END; (*----- End search ' ' ------------------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* 'D' = Show messages older/newer than a certain date/time *)
- (*-------------------------------------------------------------------------*)
-
- 'D': BEGIN;
-
- IF our_search.search_above THEN
- found := msg_index_current^.msg_i_mb.msg_dt_in
- >= our_search.search_dt
- ELSE
- found := msg_index_current^.msg_i_mb.msg_dt_in
- <= our_search.search_dt;
-
- END; (*----- End search 'D' ------------------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* 'K' = find message by number and does contain a flag *)
- (* 'N' = find message by number and does not contain a flag *)
- (*-------------------------------------------------------------------------*)
-
- 'K', 'N': BEGIN;
-
- IF our_search.search_above THEN
- found := (msg_index_current^.msg_i_mb.msg_number
- >= our_search.search_msg_no)
- ELSE
- found := (msg_index_current^.msg_i_mb.msg_number
- <= our_search.search_msg_no);
-
- IF found THEN
- BEGIN;
- found := (msg_index_current^.msg_i_mb.msg_flag
- AND our_search.search_mf) <> 0;
- IF our_search.search_type = 'N' THEN
- found := NOT found;
- END;
-
- END;
-
- (*-------------------------------------------------------------------------*)
- (* 'L' = Find last "n" msgs *)
- (*-------------------------------------------------------------------------*)
-
- 'L': BEGIN;
-
- found := our_search.search_msg_no <> 0;
-
- IF found THEN
- found := check_hidden(msg_index_current);
-
- IF found THEN
- this_search_block^.search_msg_no := our_search.search_msg_no - 1;
-
- do_hide_check := FALSE;
-
- END; (*----- End search "L" ------------------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* 'M' = find all messages belonging to a user *)
- (*-------------------------------------------------------------------------*)
-
- 'M': BEGIN;
-
- found := (msg_index_current^.msg_i_mb.msg_to = our_search.search_str)
- OR (msg_index_current^.msg_i_mb.msg_from
- = our_search.search_str)
- OR (msg_index_current^.msg_i_mb.msg_to_at
- = our_search.search_str)
- OR (msg_index_current^.msg_i_mb.msg_from_at
- = our_search.search_str);
-
- END;
-
- (*-------------------------------------------------------------------------*)
- (* 'Q' = find all read messages to user *)
- (* 'R' = find all unread messages to user *)
- (*-------------------------------------------------------------------------*)
-
- 'Q', 'R': BEGIN;
-
- found := match_str(msg_index_current^.msg_i_mb.msg_to,
- our_search.search_str);
-
- IF found THEN
- BEGIN;
- IF our_search.search_type = 'Q' THEN
- found := (msg_index_current^.msg_i_mb.msg_flag
- AND mf_read) <> 0
- ELSE
- found := (msg_index_current^.msg_i_mb.msg_flag
- AND not_read_flags) = 0;
- END;
-
- END;
-
- (*-------------------------------------------------------------------------*)
- (* 'T' = find all messages of a certain type *)
- (*-------------------------------------------------------------------------*)
-
- 'T': BEGIN;
-
- found := msg_index_current^.msg_i_mb.msg_type
- = our_search.search_str[1];
-
- END;
-
- (*-------------------------------------------------------------------------*)
- (* 'C' = Checks the current user class. This is really here for action *)
- (* file stuff. The result is not based on the message *)
- (*-------------------------------------------------------------------------*)
-
- 'C': BEGIN;
-
- found := active_tcb^.uid_data.user_class
- <= our_search.search_user_class;
-
- END;
-
- (*-------------------------------------------------------------------------*)
- (* 'G' = Checks the current logged on user. This is here for action *)
- (* file stuff. The result is not based on the message *)
- (*-------------------------------------------------------------------------*)
-
- 'G': BEGIN;
-
- found := active_tcb^.uid_data.user_id = our_search.search_str;
-
- END;
-
-
- (*-------------------------------------------------------------------------*)
- (* Catch bugs *)
- (*-------------------------------------------------------------------------*)
-
- ELSE
- BEGIN;
- WRITELN;
- WRITELN('Search error -- ', our_search.search_type,
- ' -- ', ORD(our_search.search_type));
- WRITELN;
- RUNERROR(msg_runerr);
- END;
-
- END; (*----- End search case statement --------------------------------------*)
-
- (*---------------------------------------------------------------------------*)
- (* Invert as needed *)
- (*---------------------------------------------------------------------------*)
-
- {$IFDEF DEBUG3D}
- IF BYTE(our_search.search_invert) > 1 THEN
- BEGIN;
- dump_reason('Bad search arg....');
- dump_state;
- dump_trace;
- dump_action_all;
- dump_search_chain(search);
- dump_hex_addr(@our_search, LENGTH(our_search));
- RUNERROR(msg_runerr);
- END;
-
- IF BYTE(found) > 1 THEN
- BEGIN;
- dump_reason('Bad state of found switch');
- dump_hex_addr(@found, 1));
- dump_state;
- dump_trace;
- RUNERROR(msg_runerr);
- END;
-
- {$ENDIF}
-
-
- found := our_search.search_invert XOR found;
-
- (*---------------------------------------------------------------------------*)
- (* For special conditions, make sure we don't find a killed message when we *)
- (* didn't want one *)
- (*---------------------------------------------------------------------------*)
-
- IF found AND nok_switch
- AND ((msg_index_current^.msg_i_mb.msg_flag AND mf_kill) <> 0) THEN
- found := FALSE;
-
- (*---------------------------------------------------------------------------*)
- (* Indentation VIOLATION ends here *)
- (*---------------------------------------------------------------------------*)
-
- (*-----------------------------------------------------------------*)
- (* We should loop again to AND a search condition *)
- (*-----------------------------------------------------------------*)
-
- b := found AND (our_search.search_next <> NIL);
-
- (*-----------------------------------------------------------------*)
- (* If so then chain to the next search *)
- (*-----------------------------------------------------------------*)
-
- IF b THEN
- BEGIN;
- this_search_block := our_search.search_next;
- our_search := this_search_block^;
- END;
-
- (*-----------------------------------------------------------------*)
- (* Loop until a search fails or we run out of searches *)
- (*-----------------------------------------------------------------*)
-
- UNTIL NOT b;
-
- (*-------------------------------------------------------------------*)
- (* Switch back to main search block *)
- (*-------------------------------------------------------------------*)
-
- IF this_search_block <> search THEN
- BEGIN;
- this_search_block := search;
- our_search := search^;
- END;
-
- (*-------------------------------------------------------------------*)
- (* See if message should be hidden from user *)
- (*-------------------------------------------------------------------*)
-
- IF found AND do_hide_check THEN
- found := check_hidden(msg_index_current);
-
- (*-------------------------------------------------------------------*)
- (* If we didn't find the right one and there are more to search *)
- (* then point to the next message to be tested *)
- (*-------------------------------------------------------------------*)
-
- IF (NOT found) AND (msg_index_current <> NIL) THEN
- BEGIN;
- IF our_search.search_one_only THEN
- msg_index_current := NIL
- ELSE
- IF ascend THEN
- msg_index_current := msg_index_current^.msg_i_next
- ELSE
- msg_index_current := msg_index_current^.msg_i_last;
- END;
-
- END; (*----- End search loop ------------------------------------------*)
-
- (*-----------------------------------------------------------------------*)
- (* Set the search results *)
- (*-----------------------------------------------------------------------*)
-
- IF found THEN
- search^.search_last := msg_index_current
- ELSE
- search^.search_last := NIL;
-
- search^.search_fi := our_search.search_fi;
-
- END;